﻿using Sustainalytics.Blob;
using Sustainalytics.Entities;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Sustainalytics.Alerts.AlertsEngine
{
    public class BlobHelper : IBlobHelper
    {
        private const string _alertsRecurrenceDateFormat = "yyyy-MM-dd HH:mm";
        private string _recurringAlertsSessionStore = "RecurringAlertsSession.txt";
        private IBlobManager _blobManager;

        public DateTime NextAlertSessionSendingDate { get; set; }
        public DateTime NextAlertSessionCollectionDate { get; set; }
        public DateTime LastSemiMonthlyAlertSession { get; set; }
        public List<Guid> UnservedClients { get; set; }

        public BlobHelper(IBlobManager blobManager)
        {
            _blobManager = blobManager;
        }
        public BlobHelper(string storageAccountConnectionString, string blobContainer, DeploymentLocation deploymentLocation)
        {
            _blobManager = BlobManager.Initialize(storageAccountConnectionString, blobContainer, deploymentLocation);
        }

        public void ReadBlob()
        {
            var blobExistsTask = _blobManager.BlobExists(_recurringAlertsSessionStore);

            if (blobExistsTask.Wait(TimeSpan.FromSeconds(5)))
            {
                if (blobExistsTask.Result)
                {
                    var blobDownloadTask = _blobManager.DownloadText(_recurringAlertsSessionStore);

                    if (blobDownloadTask.Wait(TimeSpan.FromSeconds(5)))
                    {
                        var recurringAlertsSession = blobDownloadTask.Result.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                        ReadDetails(recurringAlertsSession);
                    }
                    else
                    {
                        throw new TimeoutException(string.Format("The blob '{0}' could not be downloaded within the alloted time of 5 seconds.", _recurringAlertsSessionStore));
                    }
                }
                else
                {
                    throw new TimeoutException(string.Format("The blob '{0}' does not exist.", _recurringAlertsSessionStore));
                }
            }
            else
            {
                throw new TimeoutException(string.Format("The blob '{0}' could not be checked for existence within the alloted time of 5 seconds.", _recurringAlertsSessionStore));
            }

        }

        public void  WriteBlob()
        {
            var alertSessionInfoList = new List<string> { NextAlertSessionSendingDate.ToString(_alertsRecurrenceDateFormat) };
            alertSessionInfoList.Add(NextAlertSessionCollectionDate.ToString(_alertsRecurrenceDateFormat));
            alertSessionInfoList.Add(LastSemiMonthlyAlertSession.ToString(_alertsRecurrenceDateFormat));
            
            if (UnservedClients != null && UnservedClients.Count > 0)
                alertSessionInfoList = alertSessionInfoList.Concat(UnservedClients.Select(g => g.ToString())).ToList();

            var alertSessionInfo = string.Join(Environment.NewLine, alertSessionInfoList);

            var uploadTextTask = _blobManager.UploadText(_recurringAlertsSessionStore, alertSessionInfo);

            if (!uploadTextTask.Wait(TimeSpan.FromSeconds(120)))
            {
                throw new TimeoutException(
                    string.Format("The following content could not be uploaded in 5 seconds into blob '{0}': <br/>{1}",
                    _recurringAlertsSessionStore, alertSessionInfo));
            }
        }

        private void ReadDetails(string[] lines)
        {
            NextAlertSessionSendingDate = DateTime.Parse(lines[0]);

            NextAlertSessionCollectionDate = DateTime.Parse(lines[1]);
            LastSemiMonthlyAlertSession = DateTime.Parse(lines[2]);

            UnservedClients = lines.Skip(3).Select(x => new Guid(x)).ToList();
        }
    }
}
